home *** CD-ROM | disk | FTP | other *** search
/ Night Owl 6 / Night Owl's Shareware - PDSI-006 - Night Owl Corp (1990).iso / 029a / readm110.zip / README.PAS < prev   
Pascal/Delphi Source File  |  1990-01-31  |  24KB  |  575 lines

  1. program readme;
  2. { Name:        Readme.pas -> Readme.exe                   }
  3. { Version:     1.10                                       }
  4. { Date:        January 2, 1990                            }
  5. { Purpose:     a text file browse utility                 }
  6. { Compiler:    Turbo Pascal 5.50                          }
  7. { Hardware:    XT,AT,386 or PS/2                          }
  8. { Video:       CGA,MDA,Herc,EGA or VGA                    }
  9. { Video Modes: 2, 3 or 7                                  }
  10. { By:          J. Rockford Cogar                          }
  11. { Company:     Nucleus Inc                                }
  12. { Address:     761 Emory Valley Road, Oak Ridge, TN 37830 }
  13. { Rights:      Use this code any way you want             }
  14. { Parameters:  README <filename>                          }
  15.  
  16. { -------------------- About Video 'Snow' ---------------------------------- }
  17. { This is a rewrite of a Turbo 'C' program that used to include code         }
  18. { to deal with CGA write contention problems ('snow'). That code was         }
  19. { removed because all Nucleus Inc. software requires EGA or VGA video        }
  20. { systems that do not have 'snow'. Late in January 1990, I will release      }
  21. { the Turbo 'C' version of README. That program will contain video functions }
  22. { that avoids CGA 'snow'.                                                    }
  23. { -------------------------------------------------------------------------------- }
  24.  
  25. { ----------------------- Constants ---------------------------------------------- }
  26. CONST
  27.   DEFAULT_EXT : string[4]  = '.c';  { default file extension }
  28.   NOFILE      : string[15] = 'File Not Found';
  29.   READERROR   : string[16] = 'File Read Error';
  30.   RAMERROR    : string[15] = 'Not Enough RAM';
  31.   NORMAL      : string[19] = 'Normal Termination.';
  32.   WRONGVIDEO  : string[30] = 'Error. can only use text mode';
  33.   DEFAULT     : string[65] = 'readme.doc';  { file to load when none was specified on the command line }
  34.   SEARCHING   : string[10] = 'Searching';
  35.   SPROMPT     : string[6]  = 'Find:';
  36.   AUTHOR      : string[27] = 'Author: J. Rockford Cogar';
  37.   PGNAME      : string[62] = 'README.EXE File Browser. by: Nucleus Inc. Oak Ridge TN 37830';
  38.   WRIT        : string[28] = 'Written in Turbo Pascal 5.5';
  39.   LINEPR      : string[15] = 'Reading Record:';
  40.   STAT1       : string[69] = 'Row: 0    of:      in RAM          Left Column: 0   Right Column: 79';
  41.   STAT2       : string[55] = 'Up = |   Down = |   Left = -   Right = -   Exit = Esc';
  42.   STAT3       : string[52] = 'Help = F1   End of File = End    Ascii Search = F9';
  43.   HELP1       : string[47] = 'Home = Top of File         End = End of File';
  44.   HELP2       : string[46] = 'PgUp = Page Up             PgDn = Page Down';
  45.   HELP3       : string[54] = 'Up Arrrow = Scroll Up      Down Arrrow = Scoll Down';
  46.   HELP4       : string[57] = 'Left Arrrow = Scroll Left  Right Arrrow = Scroll Right';
  47.   HELP5       : string[47] = 'Esc = Exit to DOS          F9  String Search';
  48.   HELP6       : string[26] = 'A = Repeat String Search';
  49.   SIDEJUMP     = 20;   { columns to scroll sideways }
  50.   SEARLEN      = 20;   { number of bytes in a search string }
  51.   NORMALEXIT   = 0;    { normal exit code to DOS }
  52.   ERROREXIT    = 1;    { error exit code to DOS }
  53.   VIDEOEXIT    = 2;    { wrong video EXIT }
  54.   NUMBLINES    = 9000; { max number of allowed lines  }
  55.   TEXTCOLOR    = 31;   { color to show normal text in }
  56.   STATUSCOLOR  = 49;   { command/status color         }
  57.   BLINKCOLOR   = 207;  { blinking color }
  58.   FINDCOLOR    = 79;   { color of found strings }
  59.   PAGESIZE     = 21;   { pageup/pagedown line lengths }
  60.   _ESC         = 1;    { Esc scan code }
  61.   _PGUP        = 73;   { Page Up key }
  62.   _PGDN        = 81;   { Page DN key }
  63.   _UPAR        = 72;   { Up arrow key }
  64.   _DNAR        = 80;   { down arrow key }
  65.   _F9          = 67;   { F9 key }
  66.   _F1          = 59;   { F1 key }
  67.   _RIAR        = 77;   { right arrow key }
  68.   _LEAR        = 75;   { left arraow key }
  69.   _HOME        = 71;   { Home key }
  70.   _END         = 79;   { End key }
  71.   _H           = 35;   { 'h' key }
  72.   _X           = 45;   { 'x' key }
  73.   _S           = 31;   { 's' key }
  74.   _A           = 30;   { 'a' key }
  75.   LEFTMAX      = 175;  { greatest allowed left edge of the display }
  76. { ----------------------- Constants ---------------------------------------------- }
  77.  
  78. { ----------------------- Special Data TYPES ---------------------------------------------- }
  79. TYPE
  80.   BUFF_TYPE   = string[254];     { the type that a buffer line is }
  81.   BUFFER_PTR  = ^BUFF_TYPE;      { pointer to a 254 byte string }
  82.   SEARCH_TYPE = string[SEARLEN]; { string of a specified length for string search uses }
  83.   STRING128   = string[128];     { filename string type. (command line params can be this long) }
  84. { ----------------------- Special Data TYPES ---------------------------------------------- }
  85.  
  86. { ----------------------- Global Variables ---------------------------------------------- }
  87. VAR
  88.   linestr   : SEARCH_TYPE;                        { processed search string }
  89.   iname     : STRING128;                          { filename var }
  90.   buffer    : array [0..NUMBLINES] of BUFFER_PTR; { pointers to 9000 strings }
  91.   max       : integer;                            { loop stop point }
  92.   key       : integer;                            { keyboard scan code value }
  93.   refresh   : boolean;                            { refresh the screen }
  94.   star      : integer;                            { first text line to display }
  95.   row       : integer;                            { row to display }
  96.   left      : integer;                            { left edge of screen }
  97.   find      : integer;                            { set to -1 if no string was found }
  98. { ----------------------- Global Variables ---------------------------------------------- }
  99.  
  100. { ---- link in assembly language functions (faster & smaller than using standard libraries) ---- }
  101. procedure snowputc(col, row, color, outch, numb: word); external;
  102. procedure cursorxy(col, row: byte); external;
  103. function  getscode: integer; external;
  104. procedure puts(strg :string); external;
  105. function  getvmode: integer; external;
  106. function  readkbd: integer; external;
  107. function  cgets(VAR strg : SEARCH_TYPE): integer; external;
  108. procedure snowwrite(col, row: integer; color: byte; ptr: buffer_ptr; soff, maxchars, clrchar: integer); external;
  109. {$L conio.obj }  { assemble CONIO.ASM (with Turbo Assembler) to make CONIO.OBJ }
  110.  
  111. { setup a different heap error handler }
  112. { ------------------------- Begin HeapFunc --------------------------------------- }
  113. {$F+} function HeapFunc(Size: word): integer; {$F-}
  114. begin
  115.   HeapFunc:=1;
  116. end;
  117. { ------------------------- End HeapFunc   --------------------------------------- }
  118.  
  119. { clear the screen, write exit msg & go to DOS }
  120. { ------------------------- Begin ExiToDos --------------------------------------- }
  121. procedure ExitToDos(ret :integer; msg: string);
  122. begin
  123.  
  124.   if (ret <> VIDEOEXIT) then
  125.     begin
  126.       snowputc(0,0,TEXTCOLOR,32,2000);    { clear the screen }
  127.     end;
  128.  
  129.   cursorxy(0,0);                      { mode the cursor  }
  130.   puts(msg);                          { display exit msg }
  131.   halt(ret);                          { return an errorlevel code }
  132. end;
  133. { ------------------------- End ExitToDos   --------------------------------------- }
  134.  
  135. { this draws the help screen }
  136. { ------------------------- Begin Help --------------------------------------- }
  137. procedure help;
  138.  VAR
  139.   ky : integer;  { dummy var for readkbd() }
  140. begin
  141.   { all messages are global typed constants }
  142.   snowputc(0,1,TEXTCOLOR,32,1760);                  { clear the data area }
  143.  
  144.   snowwrite(8, 2, TEXTCOLOR,addr(PGNAME),0,80,80);  { program Name    }
  145.   snowwrite(0, 4, TEXTCOLOR,addr(HELP1),0,80,80);   { Help message #1 }
  146.   snowwrite(0, 6, TEXTCOLOR,addr(HELP2),0,80,80);   { Help message #2 }
  147.   snowwrite(0, 8, TEXTCOLOR,addr(HELP3),0,80,80);   { Help message #3 }
  148.   snowwrite(0, 10,TEXTCOLOR,addr(HELP4),0,80,80);   { Help message #4 }
  149.   snowwrite(0, 12,TEXTCOLOR,addr(HELP5),0,80,80);   { Help message #5 }
  150.   snowwrite(0, 14,TEXTCOLOR,addr(HELP6),0,80,80);   { Help message #6 }
  151.  
  152.   refresh:=TRUE;  { redraw screen later }
  153.   ky:=readkbd;    { pause for a scan code from kbd }
  154. end;
  155. { ------------------------- End Help   --------------------------------------- }
  156.  
  157. { backwards POS(). return the offset into STRING str of CHAR ch. ret -1 if not found }
  158. { ------------------------- Begin rpos   --------------------------------------- }
  159. function rpos(str: string; ch: char): integer;
  160. Var  i:   integer;  { loop index }
  161.      loc: integer;  { location of the find }
  162. begin
  163.   i:=length(str); { string length   }
  164.   loc:=-1;        { assume failure! }
  165.  
  166.   { ---------------------- search loop ------------------------------- }
  167.   while (i > 0) and (loc = -1) do  { loop backwards through the string }
  168.     begin
  169.  
  170.       if (str[i] = ch) then  { got a match }
  171.         begin
  172.           loc:=i;  { save the index of the location }
  173.         end;
  174.  
  175.       dec(i);  { look one byte leftwards }
  176.     end;
  177.   { ---------------------- search loop ------------------------------- }
  178.  
  179.   rpos:=loc;  { the location of the find. -1 if no find }
  180. end;
  181. { ------------------------- End rpos   --------------------------------------- }
  182.  
  183. { this draws the screen for the text file browser }
  184. { ------------------------- begin video_setup --------------------------------------- }
  185. procedure Video_Setup;
  186.  Var
  187.    vmode: integer;  { current video mode }
  188. begin
  189.   vmode:=getvmode; { get current video mode }
  190.  
  191.   if (vmode < 2) or (vmode > 7) or (vmode = 4) or (vmode = 5) or (vmode = 6) then
  192.     begin
  193.       ExitToDos(VIDEOEXIT,WRONGVIDEO);
  194.     end;
  195.  
  196.   snowputc(0,1,TEXTCOLOR,32,1760);                 { clear the screen  }
  197.   snowwrite(8,10,TEXTCOLOR,addr(PGNAME),0,72,72);  { program Name      }
  198.   snowwrite(0, 0,STATUSCOLOR,addr(STAT1),0,80,80); { status message #1 }
  199.  
  200.   snowputc(0,23,STATUSCOLOR,32,20);
  201.   snowwrite(20,23,STATUSCOLOR,addr(STAT2),0,60,60);  { status message #2 }
  202.  
  203.   snowputc(0,24,STATUSCOLOR,32,20);
  204.   snowwrite(20,24,STATUSCOLOR,addr(STAT3),0,60,60);  { status message #3 }
  205.   snowputc(25,23,STATUSCOLOR,24,1);          { ascii  24 up    }
  206.   snowputc(36,23,STATUSCOLOR,25,1);          { ascii  25 down  }
  207.   snowputc(47,23,STATUSCOLOR,27,1);          { ascii  27 left  }
  208.   snowputc(59,23,STATUSCOLOR,26,1);          { ascii  26 right }
  209.  
  210.   cursorxy(0,24);  { home the cursor }
  211. end;
  212. { ------------------------- End   video_setup --------------------------------------- }
  213.  
  214. { this initializes a filename variable }
  215. { ------------------------- begin   Set_Filename --------------------------------------- }
  216. procedure Set_Filename(VAR ifname: STRING128);
  217. Var
  218.  dotloc: integer; { location of the dot in the filename }
  219. begin
  220.  
  221.     if (paramcount > 0) then
  222.       begin
  223.         ifname:=paramstr(1);  { fetch com line filename }
  224.       end
  225.     else
  226.       begin
  227.         ifname:=DEFAULT;  { use the default filename when none was specified }
  228.       end;
  229.  
  230.     dotloc:=pos('.',ifname);  { get offset of '.' }
  231.  
  232.     if (dotloc = 0) then { append a default extension on the filename var }
  233.       begin
  234.         ifname:=ifname + DEFAULT_EXT;
  235.       end;
  236.  
  237. end;
  238. { ------------------------- End   Set_Filename --------------------------------------- }
  239.  
  240. { this reads the file from disk into global variable: buffer[] }
  241. { ------------------------- Begin Read_File --------------------------------------- }
  242. function Read_File(ifname: string): integer;
  243. Var
  244.   inf     : text;       { file pointer               }
  245.   strg    : string;     { scaler string var          }
  246.   line    : integer;    { line index                 }
  247.   len     : integer;    { line length                }
  248.   linestr : string[20]; { str to show current line # }
  249. begin
  250.    line:= 0;       { zero line counter }
  251.  
  252.    assign(inf,ifname);
  253.  
  254.    {$I-} reset(inf); {$I+}
  255.  
  256.    if (IOResult <> 0) then ExitToDos(ERROREXIT,NOFILE);  { no file. exit }
  257.  
  258.    snowwrite(24,12,TEXTCOLOR,addr(LINEPR),0,15,15);  { status msg }
  259.  
  260.    { ------- write the root of the filename on the CRT ------ }
  261.    if (length(ifname) < 19) then
  262.      begin
  263.        snowwrite(0,23,STATUSCOLOR,addr(ifname),0,19,19);  { write the filename on the screen }
  264.      end
  265.    else  { a complex filename is being processed }
  266.      begin
  267.        len:=rpos(ifname,'\');              { get offset into string of '\' }
  268.        linestr:=copy(ifname, len + 1, 19); { copy just the root into linestr }
  269.        snowwrite(0,23,STATUSCOLOR,addr(linestr),0,19,19);  { write the filename on the screen }
  270.      end;
  271.  
  272.    { ---- Read lines from file Loop ---- }
  273.    while NOT EOF(inf) and (line < NUMBLINES) and (MaxAvail > 1024) do
  274.      begin
  275.        {$I-}
  276.        readln(inf,strg);              { read a line from the file }
  277.        {$I+}
  278.  
  279.        if (IOResult <> 0) then  { read error }
  280.          begin
  281.            close(inf);
  282.            ExitToDos(ERROREXIT,READERROR);  { Read error. exit }
  283.          end;
  284.  
  285.        len:=length(strg) + 1;         { get line length }
  286.        getmem(buffer[line], len);     { get heap RAM for the array line }
  287.  
  288.        if (buffer[line] = NIL) then { if getmem() failed }
  289.          begin
  290.            close(inf);
  291.            ExitToDos(ERROREXIT,RAMERROR);
  292.          end;
  293.  
  294.        move(strg,buffer[line]^,len);  { copy the scaler string to the array }
  295.  
  296.        if ( (line mod 64) = 0) then  { every 64 lines update count on the CRT }
  297.          begin
  298.            str(line,linestr);             { convert line index to string }
  299.            snowwrite(40,12,TEXTCOLOR,addr(linestr),0,6,6);
  300.          end;
  301.  
  302.        inc(line); { inc the line counter }
  303.      end;  { while end }
  304.  
  305.    close(inf);
  306.  
  307.    strg:=' ';  { reinit to a known state }
  308.    { ----------- padd lines for very short text files ---------------- }
  309.    while (line <= PAGESIZE) do
  310.      begin
  311.        getmem(buffer[line], 3);    { get heap RAM for the ' ' empty array lines }
  312.        move(strg,buffer[line]^,3); { copy the scaler string to the array }
  313.        inc(line);                  { inc the line counter }
  314.      end;
  315.    { ----------- padd lines for very short text files ---------------- }
  316.  
  317.    str(line - 1,linestr);             { convert line index to string }
  318.    snowwrite(14,0,STATUSCOLOR,addr(linestr),0,5,5);
  319.    snowputc(0,10,TEXTCOLOR,32,240);
  320.  
  321.    Read_File:=line - 1;
  322. end;
  323. { ------------------------- End   Read_File --------------------------------------- }
  324.  
  325. { this displays the text data on the CRT }
  326. { ------------------------- Begin Write_Data --------------------------------------- }
  327. procedure Write_Data(star, left, find: integer);
  328. Var
  329.   starstr:   string[34]; { counter display string }
  330.   line   :   integer;    { data buffer index      }
  331.   row    :   integer;    { CRT row index          }
  332.   lstop  :   integer;    { loop stop point        }
  333. begin
  334.  
  335.   { note: buffer[] is a global variable }
  336.  
  337.   str(star,starstr);      { convert start index to string }
  338.   snowwrite(5,0,STATUSCOLOR,addr(starstr),0,5,5);
  339.  
  340.   str(left,starstr);      { left edge column }
  341.   snowwrite(48,0,STATUSCOLOR,addr(starstr),0,3,3);
  342.  
  343.   str(left + 79,starstr);  { Right edge column }
  344.   snowwrite(66,0,STATUSCOLOR,addr(starstr),0,3,3);
  345.  
  346.   row:=1;                 { first line to write text to }
  347.   lstop:=star + PAGESIZE; { set loop stop point         }
  348.  
  349.   for line:=star to lstop do
  350.     begin
  351.  
  352.       if (find > -1) and (line = find) then snowwrite(0,row,FINDCOLOR,addr(buffer[line]^),left,80,80)
  353.         else snowwrite(0,row,TEXTCOLOR,addr(buffer[line]^),left,80,80);  { write the text to the CRT }
  354.  
  355.       inc(row);  { next CRT row }
  356.     end;
  357.  
  358. end;
  359. { ------------------------- End   Write_Data --------------------------------------- }
  360.  
  361. { this does the string search. (case sensitive) }
  362. { ------------------------- Begin Search --------------------------------------- }
  363. function search(start, max : integer; sstr: string) : integer;
  364.  VAR
  365.    i : integer;  { loop index                }
  366.    ok: byte;     { position of the substring }
  367. begin
  368.    { note: buffer[] is a global variable }
  369.  
  370.    ok:=0;     { assume failure   }
  371.    i:=start;  { loop start point }
  372.  
  373.    { search through the buffer for the string }
  374.    while (ok = 0) and (i <= max) do
  375.      begin
  376.        ok:=pos(sstr, buffer[i]^);  { search the text line }
  377.        inc(i);                     { point to the next text line }
  378.      end;
  379.  
  380.    if (i <= (max + 1) ) and (ok > 0) then
  381.      begin
  382.        search:=i - 1;  { return line of the find }
  383.      end
  384.    else
  385.      begin
  386.        search:=-1;  { no find }
  387.      end;
  388.  
  389. end;
  390. { ------------------------- End Search   --------------------------------------- }
  391.  
  392. { prompt user for string to search, then do the search }
  393. { ------------------------- Begin String_Search  --------------------------------------- }
  394. function String_Search(key: integer; VAR refresh: boolean; VAR star: integer): integer;
  395. Var
  396.   off_set   : integer;     { offset in start of string search }
  397.   len       : integer;     { line length                      }
  398.   lfind     : integer;     { line of the search find          }
  399.   searchstr : SEARCH_TYPE; { ascii search string              }
  400. begin
  401.   { linestr is a global variable }
  402.  
  403.   if (key <> _A) then
  404.     begin
  405.       cursorxy(6,24);                                    { home the cursor }
  406.       snowwrite(0,24,STATUSCOLOR,addr(SPROMPT),0,20,20); { write prompt    }
  407.       searchstr[0]:=#14;                                 { max numb bytes of input }
  408.       len:=cgets(searchstr);                             { get string from the user }
  409.       cursorxy(0,24);                                    { home the cursor }
  410.       linestr:=copy(searchstr,2,len);                    { copy the useful data to another string }
  411.       off_set:=0;                                        { start search on the current line }
  412.     end
  413.   else
  414.     begin
  415.       off_set:=1; { start search on line below current one }
  416.     end;
  417.  
  418.   snowwrite(0,24,BLINKCOLOR,addr(SEARCHING),0,20,20);  { searching msg }
  419.   len:=search(star + off_set,max,linestr);
  420.  
  421.   if (len > -1) then  { if string was found }
  422.     begin
  423.       refresh:=TRUE;                                          { set to refresh the data on the CRT }
  424.       star:=len;                                              { first line to display }
  425.       lfind:=len;                                             { line of the find }
  426.       if (lfind < 0) then lfind:=0;                           { range check find }
  427.       if (star > (max - PAGESIZE)) then star:=max - PAGESIZE; { last page case for starting line }
  428.     end
  429.   else
  430.     begin
  431.       lfind:=-1;  { no string was found }
  432.     end;
  433.  
  434.   snowputc(0,24,STATUSCOLOR,32,20);
  435.   snowwrite(20,24,STATUSCOLOR,addr(STAT3),0,80,80);  { status message #3 }
  436.  
  437.   String_Search:=lfind;  { return the line number of the search find }
  438. end;
  439. { ------------------------- End   String_Search  --------------------------------------- }
  440.  
  441. { ------------------------- Begin Init_Globals  --------------------------------------- }
  442. procedure Init_Globals;
  443. begin
  444.    HeapError:=@HeapFunc; { set up our own getmem() error handler }
  445.    left:=0;              { initial left edge is zero             }
  446.    refresh:=FALSE;       { no refresh yet                        }
  447.    find:=-1;             { no find yet                           }
  448.    star:=0;              { start at first line                   }
  449.    key:=0;               { init scan code to zero                }
  450.    linestr:=' ';         { initail search string                 }
  451. end;
  452. { ------------------------- End   Init_Globals  --------------------------------------- }
  453.  
  454. { ------------------------- Begin Main (ie: main loop proc) ------------------ }
  455. begin
  456.    Init_Globals;           { initialize global variables              }
  457.  
  458.    Video_Setup;            { draw the screen                          }
  459.  
  460.    Set_Filename(iname);    { initialize the filename variable (iname) }
  461.  
  462.    max:=Read_File(iname);  { read the file from disk into buffer[]    }
  463.  
  464.    Write_Data(0, 0, -1);   { write data to the CRT                    }
  465.  
  466.   { ------------------------------ Main Loop --------------------------------- }
  467.    while (key <> _ESC) do  { loop till the Esc key is pressed }
  468.      begin
  469.        key:=getscode;  { get current scan key code }
  470.  
  471.        { -------------------------- Case Block ---------------------------- }
  472.        case (key) of  { begin case }
  473.             _PGUP:   { PageUp key }
  474.                      begin
  475.                        star:=star - PAGESIZE;
  476.  
  477.                        if (star < 0) then
  478.                          begin
  479.                            star:=0;
  480.                          end;
  481.  
  482.                      refresh:=TRUE;
  483.  
  484.                      end;
  485.             _PGDN:   { PageDown key }
  486.                      begin
  487.                        star:=star + PAGESIZE;
  488.  
  489.                        if ( (star + PAGESIZE) > max) then
  490.                          begin
  491.                            star:=max - PAGESIZE;
  492.                          end;
  493.  
  494.                      refresh:=TRUE;
  495.  
  496.                      end;
  497.             _UPAR:   { UpArrow key }
  498.                      begin
  499.  
  500.                        if (star > 0) then
  501.                          begin
  502.                            dec(star);
  503.                            refresh:=TRUE;
  504.                          end;
  505.  
  506.                      end;
  507.             _DNAR:   { Down Arrow key }
  508.                      begin
  509.  
  510.                        if ( (star + PAGESIZE) < max) then
  511.                          begin
  512.                            inc(star);
  513.                            refresh:=TRUE;
  514.                          end;
  515.  
  516.                      end;
  517.             _RIAR:   { right arrow key }
  518.                      begin
  519.                        left:=left + SIDEJUMP;
  520.                        if (left > LEFTMAX) then left:=0;
  521.                        refresh:=TRUE;
  522.                      end;
  523.             _LEAR:   { left arrow key }
  524.                      begin
  525.                        left:=left - SIDEJUMP;
  526.                        if (left < 0) then left:=0;
  527.                        refresh:=TRUE;
  528.                      end;
  529.             _HOME:   { Home key }
  530.                      begin
  531.                        star:=0;
  532.                        refresh:=TRUE;
  533.                      end;
  534.             _END :   { End key }
  535.                      begin
  536.  
  537.                        if (max >= PAGESIZE) then
  538.                          begin
  539.                            star:=max - PAGESIZE;
  540.                          end
  541.                        else
  542.                          begin
  543.                            star:=0;
  544.                          end;
  545.  
  546.                        refresh:=TRUE;
  547.                      end;
  548.             _F9,_S,_A  :   { string search keys }
  549.                      begin
  550.                        find:=String_Search(key, refresh, star); { Ascii String Search }
  551.                      end;
  552.             _H,_F1:  { 'h' key HELP Screen }
  553.                      begin
  554.                        help; { show help screen }
  555.                      end;
  556.             _X    :  { 'x' key }
  557.                      begin
  558.                        key:=_ESC;
  559.                      end;
  560.             end;      { end case }
  561.        { -------------------------- Case Block ---------------------------- }
  562.  
  563.         if (refresh) then  { if time to update CRT data }
  564.           begin
  565.             refresh:=FALSE;               { toggle to avoid doing too much CRT stuff }
  566.             Write_Data(star, left, find); { write data to the CRT }
  567.           end;
  568.  
  569.      end;    { end while loop }
  570.   { ------------------------------ Main Loop --------------------------------- }
  571.  
  572.   ExitToDos(NORMALEXIT,NORMAL);
  573. end.
  574. { ------------------------- End Main --------------------------------------- }
  575.